#define SET_IDT_TABLE_LOW32(addr) \
    ((0x00080000) + (addr & 0xffff))
#define SET_IDT_TABLE_HIGH32(dpl, type, addr) \
    (((addr & 0xffff0000)<<16) + (0x8000) + (dpl<<13) + (type<<8))

typedef struct desc_table
{
	unsigned int low32;
	unsigned int high32;
}idt_table;

// 0
void divide_error()
{
}

// 1
void debug()
{
}

// 2
void nmi()
{
}

// 3
void int3()
{
}

// 4
void overflow()
{
}

// 5
void bounds()
{
}

// 6
void invalid_opcode()
{
}

// 7
void device_invalid()
{
}

// 8 
void double_fault()
{
}

// 9
void coprocessor_seg_overrun()
{
}

// 10
void invalid_TSS()
{
}

// 11
void seg_not_present()
{
}

// 12
void stack_seg_fault()
{
}

// 13
void general_protection()
{
}

// 14
void page_fault()
{
}

// 15
void reserved()
{
}

// 16
void coprocessor_error()
{
}

// 17
void alignment_check()
{
}

// 18
void machine_check()
{
}

// 19
void SIMD_exception()
{
}

// 128
void system_call()
{
}

void idt_init()
{
    int i;
    idt_table *p_idt = (idt_table *)0x5800;

    // 0 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)divide_error);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)divide_error);
    p_idt++;

    // 1 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)debug);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)debug);
    p_idt++;

    // 2 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)nmi);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)nmi);
    p_idt++;

    // 3 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)int3);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(3, 15, (unsigned int)int3);
    p_idt++;

    // 4 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)overflow);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(3, 15, (unsigned int)overflow);
    p_idt++;

    // 5 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)bounds);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(3, 15, (unsigned int)bounds);
    p_idt++;

    // 6 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)invalid_opcode);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)invalid_opcode);
    p_idt++;

    // 7 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)device_invalid);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)device_invalid);
    p_idt++;

    // 8 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)double_fault);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)double_fault);
    p_idt++;

    // 9 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)coprocessor_seg_overrun);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)coprocessor_seg_overrun);
    p_idt++;

    // 10 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)invalid_TSS);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)invalid_TSS);
    p_idt++;

    // 11 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)seg_not_present);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)seg_not_present);
    p_idt++;

    // 12 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)stack_seg_fault);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)stack_seg_fault);
    p_idt++;

    // 13 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)general_protection);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)general_protection);
    p_idt++;

    // 14 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)page_fault);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)page_fault);
    p_idt++;

    // 15 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)reserved);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)reserved);
    p_idt++;

    // 16 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)coprocessor_error);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)coprocessor_error);
    p_idt++;

    // 17 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)alignment_check);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)alignment_check);
    p_idt++;

    // 18 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)machine_check);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)machine_check);
    p_idt++;

    // 19 
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)SIMD_exception);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)SIMD_exception);
    p_idt++;

    // 20-31
    for (i=20; i<32; i++)
    {
        p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)reserved);
        p_idt->high32 = SET_IDT_TABLE_HIGH32(0, 15, (unsigned int)reserved);
        p_idt++;
    }

    p_idt = (idt_table *)0x5800;
    p_idt += 0x80;
    p_idt->low32 = SET_IDT_TABLE_LOW32((unsigned int)system_call);
    p_idt->high32 = SET_IDT_TABLE_HIGH32(3, 15, (unsigned int)system_call);
    
}


